﻿/******************************************************************************
* File description: syringeCalculator.cpp
* Function: 计算注射器参数，用于动画显示
* Current Version: 1.0.0
* Author: JNN
* Date: 2025-07-01
*  -----
*  Copyright by 博坤生物 .
 *****************************************************************************/

#include "syringeCalculator.h"

double syringe_top_5 = 47.5;
double syringe_bot_5 = 92;
double syringe_top_10 = 27;
double syringe_bot_10 = 89;
double syringe_top_20 = 11;
double syringe_bot_20 = 79.6;

QString SyringeCalculator::consumableName = "";
QVector<QMap<QString, QString>> SyringeCalculator::_syringeList = QVector<QMap<QString, QString>>();

/** @brief 构造函数 */
SyringeCalculator::SyringeCalculator()
{

}

/** @brief 设置耗材数量 */
void SyringeCalculator::setConsumableName(QString cn){
    consumableName = cn;
    refreshSyringeParams();
}

/** @brief 将指定注射器的步数转换为mm
 *  @param idx 注射器编号
 *  @param stepNum 注射器编号
 *  @return double mm(推进高度) */
double SyringeCalculator::calStep2MM(int idx, double stepNum){      // 转化为毫米

    if(idx >= _syringeList.size()){
        return stepNum *0.01;
    }

    double syringeVolumn = 0;  // 注射器容量
    double reductionRatio = 0; // 减速比
    double circleStep = 0;     // 圈步
    double screwLead = 0;      // 导程

    reductionRatio = _syringeList[idx]["ReductionRatio"].split(":").back().toInt();
    circleStep = _syringeList[idx]["CircleStep"].toDouble();
    screwLead = _syringeList[idx]["ScrewLead"].toDouble();

    if(reductionRatio <= 0 || circleStep <= 0 || screwLead <= 0){
//        __LOG_ERROR("ReadSqlInfoFailed"+QString::number(reductionRatio) + "," + QString::number(circleStep) + "," + QString::number(screwLead));
//        __LOG_FEND(stepNum * 0.001);
        return stepNum * 0.001;
    }
    double mm = stepNum * screwLead / circleStep / reductionRatio;
//    __LOG_FEND(mm);
    return mm;
}

/** @brief 获取注射器的高度
 *  @param idx 注射器编号
 *  @return double 高度 */
double SyringeCalculator::getSyringeHeightMM(int idx){

    if(idx == 0){       // 溶靶瓶高度固定
        return 50;
    }
    if(idx >= _syringeList.size())  {  return 40;  }


    double syringeVolumn = 0;
    double insideDiameter = 0;

    insideDiameter = _syringeList[idx]["InsideDiameter"].toDouble();
    syringeVolumn = _syringeList[idx]["Type"].remove("注射器").remove("ml").toDouble();

    if(syringeVolumn <= 0 || insideDiameter <= 0){
        return 40;
    }

    double height = syringeVolumn / (3.1415926535 * std::pow(insideDiameter/2, 2)) * 1000;

    return height;

}

/** @brief 获取注射器的直径
 *  @param idx 注射器编号
 *  @return double 直径 */
double SyringeCalculator::getSyringeDiameterMM(int idx){

    if(idx == 0){       // 溶靶瓶内径固定
        return 25;
    }

    if(idx >= _syringeList.size())  {  return 22;  }


//    qDebug() << "获取注射器内径" << idx;

    double syringeVolumn = 0;
    double insideDiameter = 0;

    insideDiameter = _syringeList[idx]["InsideDiameter"].toDouble();
    syringeVolumn = _syringeList[idx]["Type"].remove("注射器").remove("ml").toDouble();

    if(insideDiameter <= 0){
//        qDebug() << "\t获取失败 " << sql;
        return 22;
    }
//    qDebug() << "\t结果" << insideDiameter;
    return insideDiameter;
}


/** @brief 对指定注射器，将速度从ml/min转换为mm/s
 *  @param idx 注射器编号
 *  @param speedMin 速度(ml/min)
 *  @return double 速度(mm/s) */
double SyringeCalculator::speedMin2s(int idx, double speedMin){

//    __LOG_FSTART("idx:"+QString::number(idx) + " speed:"+QString::number(speedMin));
    if(idx == 0)        { return 0; }
    if(idx >= _syringeList.size())  {  return 22;  }

    double insideDiameter = 0;

    insideDiameter = _syringeList[idx]["InsideDiameter"].toDouble();

    if(insideDiameter <= 0){

//        __LOG_ERROR("ReadSqlInfoFailed"+QString::number(insideDiameter));
//        __LOG_FEND(speedMin);
        return speedMin;
    }


    double res = CommonHelper::Common().minToSecond(speedMin, insideDiameter);
//    __LOG_FEND(res);
    return res;

}

/** @brief 对指定注射器，将速度从mm/s转换为ml/min
 *  @param idx 注射器编号
 *  @param speedMin 速度(mm/s)
 *  @return double 速度(ml/min) */
double SyringeCalculator::speedS2min(int idx, double speedS){

    if(idx == 0)        { return speedS; }
    if(idx >= _syringeList.size())  {  return speedS;  }

//    __LOG_FSTART("idx:"+QString::number(idx) + " speed:"+QString::number(speedS));

    double insideDiameter = 0;

    insideDiameter = _syringeList[idx]["InsideDiameter"].toDouble();

    if(insideDiameter <= 0){

//        __LOG_ERROR("ReadSqlInfoFailed"+QString::number(insideDiameter));
//        __LOG_FEND(speedS);
        return speedS;
    }


    double res = CommonHelper::Common().secondToMin(speedS, insideDiameter);
//    __LOG_FEND(res);
    return res;
}


/** @brief 获取注射器复位所在的百分比位置
 *  @param idx 注射器编号
 *  @return double 百分比位置[0,1] */
double SyringeCalculator::getSyringePercentFromInitialPosition(int idx){


    if(idx == 0){  return 0; }
    if(idx >= _syringeList.size())  {  return 1;  }

    double initialHeight = 6;       // 起始高度
    QString rateUnit;               // 单位
    int volumn = 0;                 // 体积

    initialHeight = _syringeList[idx]["InitialPosition"].toDouble();
    rateUnit = _syringeList[idx]["RateUnit"];
    volumn = _syringeList[idx]["Type"].split("m")[0].toInt();

    double percent = 0;

    if(rateUnit.contains("mL")){        // 按照注射器的尺码复位
        if(volumn <= 0){
            qDebug() << "单位转换错误 volumn =" << volumn;
        }else{
            percent = initialHeight / volumn;
        }
    }else{                              // 按照电机高度复位
        double top, bottom;
        if(volumn == 5){
            top = syringe_top_5;
            bottom = syringe_bot_5;
        }else if(volumn == 10){
            top = syringe_top_10;
            bottom = syringe_bot_10;
        }else if(volumn == 20){
            top = syringe_top_20;
            bottom = syringe_bot_20;
        }else{
            qDebug() << "单位转换错误 volumn =" << volumn;
            top = 0; bottom = 200;
        }
        qDebug() << "初始高度" << initialHeight << "顶部高度" << top << "底部高度" << bottom;
        percent = 1 - (initialHeight - top) / (bottom - top);
    }
    qDebug() << percent;

//    if(rateUnit.contains("mL")){        // 单位从mL转换为mm
//        double diam = SyringeCalculator::getSyringeDiameterMM(idx);
//        if(diam <= 0){
//            qDebug() << "单位转换错误" << "SyringeHeight=0";
//            return 0;
//        }
//        initialHeight = 4000 * initialHeight / 3.1415926 / pow(diam, 2);
//    }


//    // 电机总高度
//    double totalHeight = 200;

//    // 注射器高度
//    double syringeHeight = getSyringeHeightMM(idx);
//    // 推杆高度
//    double pushHeight = syringeHeight + 25;

//    // 注射器剩余高度 = 总高度 - 起始高度 - 推杆高度
//    double syringeRemainHeight = totalHeight - initialHeight - pushHeight;

//    // 注射器的百分比
//    if(syringeHeight == 0){
//        qDebug() << "注射器初始位置计算错误" << "SyringeHeight=0";
//        return 0;
//    }
//    double percent = syringeRemainHeight / syringeHeight;

//    if(percent > 1 || percent < 0){
//        qDebug() << "注射器初始位置计算错误" << percent << "  电机总高度" << totalHeight << "  注射器高度" << syringeHeight << "  推杆高度" << pushHeight << "  注射器剩余高度" << syringeRemainHeight;
//    }

    percent = std::min(1.0, std::max(percent, 0.0));

    qDebug() << "注射器" << idx << "初始百分比为" << percent;

    return percent;
}

void SyringeCalculator::refreshSyringeParams(){
    _syringeList.clear();
    _syringeList.push_back(QMap<QString, QString>());       // 0号位为溶靶瓶占位

    QString consumeId = CommonHelper::Common().getItemCode("3", consumableName);
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql = QString("select * from syringeMaintenance where consumablesTypes='%2'").arg(consumeId);
    query.exec(sql);
    while (query.next()) {
        _syringeList.push_back(QMap<QString, QString>());
        for(int i = 0; i < query.record().count(); i ++){
            QString fieldName = query.record().fieldName(i);
            QString value = query.record().value(i).toString();
            _syringeList.back().insert(fieldName, value);
        }
    }

    qDebug() << "刷新注射器参数" << _syringeList;

}


